package ui.tab;

import entity.Column;
import entity.Table;
import ui.AgCodeMain;
import ui.MyAbstractTableModel;
import utils.CamelCaseUtils;
import utils.DBUtil;
import utils.FreemarkerUtil;
import utils.StringUtil;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 转换参数配置页面
 * Created by liushun on 2016/11/21.
 */
public class ParamConfigTab extends JPanel {

    private JLabel pg, sxb, bqz, entity, encl, dao, serivce, control;

    private JTextField pg_txt, sxb_txt, bqz_txt, encl_txt;

    private JButton dao_btn, entity_btn, serivce_btn, control_btn, sxb_btn, encl_btn;

    private JComboBox entity_box_type, entity_box_zs, dao_box, serivce_box, control_box;

    private Map<String, String> tableMap = new HashMap<String, String>(); //缓存数据表

    public ParamConfigTab(){
        pg = new JLabel("包路径：");
        pg.setBounds(40, 28, 100, 30);
        this.add(pg);

        pg_txt = new JTextField(15);
        pg_txt.setBounds(100, 32, 250, 23);
        pg_txt.setText(AgCodeMain.config.getProperty("package.packagePath"));
        this.add(pg_txt);

        sxb = new JLabel("筛选表：");
        sxb.setBounds(40, 62, 100, 30);
        this.add(sxb);

        sxb_txt = new JTextField(15);
        sxb_txt.setBounds(100, 65, 210, 23);
        sxb_txt.setText(AgCodeMain.config.getProperty("package.tableNames"));
        sxb_txt.setEditable(false);
        this.add(sxb_txt);

        sxb_btn = new JButton("...");
        sxb_btn.setBounds(320, 65, 30, 23);
        sxb_btn.addActionListener(new ChooseTableDialog());
        this.add(sxb_btn);


        bqz = new JLabel("表前缀：");
        bqz.setBounds(40, 92, 100, 30);
        this.add(bqz);

        bqz_txt = new JTextField(15);
        bqz_txt.setBounds(100, 95, 250, 23);
        bqz_txt.setText(AgCodeMain.config.getProperty("package.tablePrefix"));
        this.add(bqz_txt);

        encl = new JLabel("自定义模板：");
        encl.setBounds(15, 122, 100, 30);
        this.add(encl);

        encl_txt = new JTextField(15);
        encl_txt.setBounds(100, 125, 210, 23);
        encl_txt.setText(AgCodeMain.config.getProperty("package.ftlPath"));
        encl_txt.setEditable(false);
        this.add(encl_txt);

        encl_btn = new JButton("...");
        encl_btn.setBounds(320, 125, 30, 23);
        encl_btn.addActionListener(new FileChooserBtnActionListener());
        this.add(encl_btn);

        entity = new JLabel("Entity层：");
        entity.setBounds(32, 152, 100, 30);
        this.add(entity);

        entity_box_type = new JComboBox(new String[]{"Entiy","DTO", "VO", "BO"});
        entity_box_type.setBounds(100, 155, 80, 23);
        this.add(entity_box_type);

        entity_box_zs = new JComboBox(new String[]{"JavaBean", "JPA注释"});
        entity_box_zs.setBounds(185, 155, 85, 23);
        this.add(entity_box_zs);

        entity_btn = new JButton("生成");
        entity_btn.setBounds(280, 155, 70, 23);
        entity_btn.addActionListener(new EntityBtnActionListener());
        this.add(entity_btn);



        dao = new JLabel("DAO层：");
        dao.setBounds(35, 182, 100, 30);
        this.add(dao);


        dao_box = new JComboBox(new String[]{"Mapper SqlXMl"});
        dao_box.setBounds(100, 185, 170, 23);
        this.add(dao_box);

        dao_btn = new JButton("生成");
        dao_btn.setBounds(280, 185, 70, 23);
        dao_btn.addActionListener(new DaoBtnActionListener());
        this.add(dao_btn);


        serivce = new JLabel("Service层：");
        serivce.setBounds(22, 212, 100, 30);
        this.add(serivce);


        serivce_box = new JComboBox(new String[]{"普通Service", "继承BaseService"});
        serivce_box.setBounds(100, 215, 170, 23);
        this.add(serivce_box);


        serivce_btn = new JButton("生成");
        serivce_btn.setBounds(280, 215, 70, 23);
        serivce_btn.addActionListener(new ServiceBtnActionListener());
        this.add(serivce_btn);


        control = new JLabel("Controller层：");
        control.setBounds(5, 242, 100, 30);
        this.add(control);


        control_box = new JComboBox(new String[]{"普通Controller"});
        control_box.setBounds(100, 245, 170, 23);
        this.add(control_box);

        control_btn = new JButton("生成");
        control_btn.setBounds(280, 245, 70, 23);
        control_btn.addActionListener(new ControlBtnActionListener());
        this.add(control_btn);

        this.setLayout(null);
    }

    public void setConfig(){
        AgCodeMain.config.setProperty("package.packagePath", pg_txt.getText());
        AgCodeMain.config.setProperty("package.tableNames", sxb_txt.getText());
        AgCodeMain.config.setProperty("package.tablePrefix", bqz_txt.getText());
        AgCodeMain.config.setProperty("package.ftlPath", encl_txt.getText());
    }

    private void changeTableName(List<String> table_list, String tables) throws SQLException {
        if(tables == null || "".equals(tables)) {
            List<Table> tableList = DBUtil.queryTableList(dbName);
            for (Table t:tableList) {
                table_list.add(t.getTableName());
                tableMap.put(t.getTableName(), t.getTableDescription());
            }
        }else{
            String[] strList = tables.split(",");
            for (String s:strList)
                table_list.add(s);
        }
    }

    //Entity按钮生成 事件监听
    private class EntityBtnActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    List<String> table_list = new ArrayList<String>();
                    try {
                        long startTime = System.currentTimeMillis();
                        String tables = sxb_txt.getText();
                        changeTableName(table_list, tables);
                        String fileName, filePath;
                        String ftl = encl_txt.getText();
                        if(ftl == null || "".equals(ftl)){
                            fileName = "entity.ftl";
                            filePath = AgCodeMain.filePath + "/ftl";
                        }else{
                            fileName = ftl.substring(ftl.lastIndexOf("\\")+1, ftl.length());
                            filePath = ftl.substring(0, ftl.lastIndexOf("\\")+1);
                        }
                        for(String table:table_list) {
                            String tableCase = CamelCaseUtils.toCapital(CamelCaseUtils.deletePrefix(bqz_txt.getText(), table), true);
                            if(tableCase!=null) {
                                List<Column> list = DBUtil.queryColumnList(table);
                                Map data = new HashMap<>();
                                String pg = pg_txt.getText().replaceAll(" ", "");
                                String tableDesc = tableMap.get(table);
                                String beanType = "entity";
                                switch (entity_box_type.getSelectedIndex()){
                                    case 0:
                                        if (pg != null && !"".equals(pg))
                                            pg = "package " + pg + ".entity;\n";
                                        else
                                            pg = "package entity;\n";
                                        break;
                                    case 1:
                                        if (pg != null && !"".equals(pg))
                                            pg = "package " + pg + ".dto;\n";
                                        else
                                            pg = "package dto;\n";
                                        tableDesc = tableDesc+"扩展";
                                        tableCase = tableCase+"DTO";
                                        beanType = "dto";
                                        break;
                                    case 2:
                                        if (pg != null && !"".equals(pg))
                                            pg = "package " + pg + ".vo;\n";
                                        else
                                            pg = "package vo;\n";
                                        tableDesc = tableDesc+"扩展";
                                        tableCase = tableCase+"VO";
                                        beanType = "vo";
                                        break;
                                    case 3:
                                        if (pg != null && !"".equals(pg))
                                            pg = "package " + pg + ".bo;\n";
                                        else
                                            pg = "package bo;\n";
                                        tableDesc = tableDesc+"扩展";
                                        tableCase = tableCase+"BO";
                                        beanType = "bo";
                                        break;
                                }
                                if(entity_box_zs.getSelectedIndex()==1){
                                    data.put("jpaEntity", "@Entity\n");
                                    data.put("jpaTable", "@Table(name = \""+table+"\")\n");
                                    data.put("jpaId", "@Id\n    ");
                                    data.put("jpaColumn", true);
                                }
                                data.put("package", pg);
                                data.put("author", AgCodeMain.config.getProperty("java.author"));
                                data.put("dateTime", StringUtil.getToDay("yyyy-MM-dd"));
                                data.put("version", AgCodeMain.config.getProperty("java.version"));
                                data.put("tableDesc", tableDesc);
                                data.put("tableName", table);

                                data.put("class", tableCase);
                                data.put("properties", list);
                                FreemarkerUtil.write(data, fileName, filePath, AgCodeMain.filePath +"/"+beanType+"/" + tableCase + ".java");
                            }
                        }
                        JOptionPane.showMessageDialog(null, entity_box_type.getSelectedItem()+"文件创建完成, 共处理 "+table_list.size()+" 张表，耗时 "+(System.currentTimeMillis()-startTime)+" 毫秒!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    } catch (Exception e) {
                        e.printStackTrace();
                        AgCodeMain.log("数据库获取连接失败!", Color.red, true);
                        JOptionPane.showMessageDialog(null, "数据库获取连接失败!", "提示", JOptionPane.ERROR_MESSAGE);
                    }

                }
            });
        }
    }

    //Controller按钮生成 事件监听
    private class ControlBtnActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    List<String> table_list = new ArrayList<String>();
                    try {
                        long startTime = System.currentTimeMillis();
                        String tables = sxb_txt.getText();
                        changeTableName(table_list, tables);
                        String fileName, filePath;
                        String ftl = encl_txt.getText();
                        if (ftl == null || "".equals(ftl)) {
                            fileName = "controller.ftl";
                            filePath = AgCodeMain.filePath + "/ftl";
                        } else {
                            fileName = ftl.substring(ftl.lastIndexOf("\\") + 1, ftl.length());
                            filePath = ftl.substring(0, ftl.lastIndexOf("\\") + 1);
                        }
                        for (String table : table_list) {
                            String tableCase = CamelCaseUtils.toCapital(CamelCaseUtils.deletePrefix(bqz_txt.getText(), table), true);
                            if(tableCase!=null) {
                                List<Column> list = DBUtil.queryColumnList(table);
                                Map data = new HashMap<>();
                                String pg = pg_txt.getText().replaceAll(" ", "");
                                String tableDesc = tableMap.get(table);
                                String beanType = "controller/ajax";
                                if (pg != null && !"".equals(pg))
                                    pg = "package " + pg + ".controller.ajax;\n";
                                else
                                    pg = "package controller.ajax;\n";
                                data.put("package", pg);
                                data.put("author", AgCodeMain.config.getProperty("java.author"));
                                data.put("dateTime", StringUtil.getToDay("yyyy-MM-dd"));
                                data.put("version", AgCodeMain.config.getProperty("java.version"));

                                data.put("tableName", CamelCaseUtils.toCapital(CamelCaseUtils.deletePrefix(bqz_txt.getText(), table), false));
                                data.put("className", tableCase);
                                data.put("class", tableCase+"Ajax");
                                FreemarkerUtil.write(data, fileName, filePath, AgCodeMain.filePath + "/" + beanType + "/" + tableCase + "Ajax.java");
                            }
                        }
                        JOptionPane.showMessageDialog(null, "Controller文件创建完成, 共处理 "+table_list.size()+" 张表，耗时 "+(System.currentTimeMillis()-startTime)+" 毫秒!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    }catch (Exception e) {
                        e.printStackTrace();
                        AgCodeMain.log("数据库获取连接失败!", Color.red, true);
                        JOptionPane.showMessageDialog(null, "数据库获取连接失败!", "提示", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
        }
    }

    //Service按钮生成 事件监听
    private class ServiceBtnActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    List<String> table_list = new ArrayList<String>();
                    try {
                        long startTime = System.currentTimeMillis();
                        String tables = sxb_txt.getText();
                        changeTableName(table_list, tables);
                        String[] fileName = new String[]{"service.ftl", "serviceImpl.ftl"};
                        String filePath = AgCodeMain.filePath + "/ftl";
                        for (String table : table_list) {
                            String tableCase = CamelCaseUtils.toCapital(CamelCaseUtils.deletePrefix(bqz_txt.getText(), table), true);
                            if(tableCase!=null) {
                                List<Column> list = DBUtil.queryColumnList(table);
                                Map data = new HashMap<>();
                                String pg = pg_txt.getText().replaceAll(" ", "");
                                String tableDesc = tableMap.get(table);
                                String beanType = "service";
                                String[] pakage = new String[2];
                                if (pg != null && !"".equals(pg)) {
                                    pakage[0] = "package " + pg + ".service;\n";
                                    pakage[1] = "package " + pg + ".service.impl;\n";
                                }else {
                                    pakage[0] = "package service;\n";
                                    pakage[1] = "package service.impl;\n";
                                }
                                switch (serivce_box.getSelectedIndex()) {
                                    case 0:
                                        data.put("isExtends", null);
                                        break;
                                    case 1:
                                        data.put("isExtends", true);
                                        break;
                                }

                                data.put("package", pakage);
                                data.put("author", AgCodeMain.config.getProperty("java.author"));
                                data.put("dateTime", StringUtil.getToDay("yyyy-MM-dd"));
                                data.put("version", AgCodeMain.config.getProperty("java.version"));

                                data.put("tableName", CamelCaseUtils.toCapital(CamelCaseUtils.deletePrefix(bqz_txt.getText(), table), false));
                                data.put("className", tableCase);
                                data.put("tableDesc", tableDesc);
                                data.put("class", tableCase+"Service");
                                FreemarkerUtil.write(data, fileName[0], filePath, AgCodeMain.filePath + "/" + beanType + "/" + tableCase + "Service.java");
                                FreemarkerUtil.write(data, fileName[1], filePath, AgCodeMain.filePath + "/" + beanType + "/impl/" + tableCase + "ServiceImpl.java");
                            }
                        }
                        JOptionPane.showMessageDialog(null, "Service文件创建完成, 共处理 "+table_list.size()+" 张表，耗时 "+(System.currentTimeMillis()-startTime)+" 毫秒!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    }catch (Exception e) {
                        e.printStackTrace();
                        AgCodeMain.log("数据库获取连接失败!", Color.red, true);
                        JOptionPane.showMessageDialog(null, "数据库获取连接失败!", "提示", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
        }
    }

    //Dao按钮生成 事件监听
    private class DaoBtnActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    List<String> table_list = new ArrayList<String>();
                    try {
                        long startTime = System.currentTimeMillis();
                        String tables = sxb_txt.getText();
                        changeTableName(table_list, tables);
                        String[] fileName = new String[]{"mapper.ftl", "sqlxml.ftl"};
                        String filePath = AgCodeMain.filePath + "/ftl";
                        String ftl = encl_txt.getText();
                        String filePath2 = filePath;
                        if (ftl != null && !"".equals(ftl)) {
                            fileName[1] = ftl.substring(ftl.lastIndexOf("\\") + 1, ftl.length());
                            filePath2 = ftl.substring(0, ftl.lastIndexOf("\\") + 1);
                        }
                        for (String table : table_list) {
                            String tableCase = CamelCaseUtils.toCapital(CamelCaseUtils.deletePrefix(bqz_txt.getText(), table), true);
                            if(tableCase!=null) {
                                List<Column> list = DBUtil.queryColumnList(table);
                                Map data = new HashMap<>();
                                String pg = pg_txt.getText().replaceAll(" ", "");
                                String tableDesc = tableMap.get(table);
                                String beanType = "mapper";
                                String[] pakage = new String[2];
                                if (pg != null && !"".equals(pg)) {
                                    pakage[0] = "package " + pg + ".mapper;\n";
                                    pakage[1] = pg + ".";
                                }else {
                                    pakage[0] = "package mapper;\n";
                                    pakage[1] = "";
                                }

                                data.put("package", pakage);
                                data.put("author", AgCodeMain.config.getProperty("java.author"));
                                data.put("dateTime", StringUtil.getToDay("yyyy-MM-dd"));
                                data.put("version", AgCodeMain.config.getProperty("java.version"));

                                data.put("tableName", table);
                                data.put("properties", list);
                                data.put("className", tableCase);
                                data.put("tableDesc", "<!-- "+tableDesc+"-->\n");
                                data.put("class", tableCase+"Mapper");
                                FreemarkerUtil.write(data, fileName[0], filePath, AgCodeMain.filePath + "/" + beanType + "/" + tableCase + "Mapper.java");
                                FreemarkerUtil.write(data, fileName[1], filePath2, AgCodeMain.filePath + "/" + beanType + "/" + tableCase + "Mapper.xml");
                            }
                        }
                        JOptionPane.showMessageDialog(null, "Mapper文件创建完成, 共处理 "+table_list.size()+" 张表，耗时 "+(System.currentTimeMillis()-startTime)+" 毫秒!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    }catch (Exception e) {
                        e.printStackTrace();
                        AgCodeMain.log("数据库获取连接失败!", Color.red, true);
                        JOptionPane.showMessageDialog(null, "数据库获取连接失败!", "提示", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
        }
    }

    //弹出文件选择对话框
    private class FileChooserBtnActionListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser jfc = new JFileChooser();
            jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            jfc.showDialog(new JLabel(), "选择");
            File file = jfc.getSelectedFile();
            if(file!=null) {
                encl_txt.setText(file.getAbsolutePath());
            }
        }
    }

    //弹出数据表选择
    private class ChooseTableDialog extends JDialog implements ActionListener {

        private JTable table;

        private JCheckBox chk;

        private MyAbstractTableModel myModel;

        private String[] columnNames = {"序号","全选","表名称", "表描述"};
        private Class[] typeArray = { Integer.class, Boolean.class, String.class, String.class};

        public ChooseTableDialog(){
            super((JFrame)null, "筛选数据表", true);
            this.setSize(300, 200);
            this.setAlwaysOnTop(true);
            this.setLocationRelativeTo(null); //居中显示
            this.setResizable(false); //不允许改变窗口大小
            this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

            table = new JTable();
            DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
            renderer.setHorizontalTextPosition(SwingConstants.LEFT);
            renderer.setForeground(Color.blue);
            table.getTableHeader().setDefaultRenderer(renderer);
            JTableHeader tableHeader = table.getTableHeader();
            tableHeader.addMouseListener(new MouseAdapter(){
                public void mouseClicked(MouseEvent e){
                    if (e.getClickCount() > 0) {
                        //获得选中列
                        int selectColumn = table.columnAtPoint(e.getPoint());
                        if (selectColumn == 1) {
                            boolean value = !chk.isSelected();
                            chk.setSelected(value);
                            myModel.selectAllOrNull(value);
                            table.repaint();
                        }
                    }
                }
            });
            JScrollPane jScrollPane = new JScrollPane(table);
            JScrollBar verticalScrollBar = jScrollPane.getVerticalScrollBar();
            verticalScrollBar.setPreferredSize(new Dimension(12, 0));
            this.add(jScrollPane);
            this.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent we) {
                    int rows = table.getRowCount();
                    List<String> tabs = new ArrayList<String>();
                    for(int i= 0 ;i<rows ;i++){
                        Boolean b = (Boolean) table.getValueAt(i, 1);
                        if(b){
                            String tableName = String.valueOf(table.getValueAt(i, 2));
                            tabs.add(tableName);
                            tableMap.put(tableName, String.valueOf(table.getValueAt(i, 3)));
                        }
                    }
                    ParamConfigTab.this.sxb_txt.setText(StringUtil.join(tabs, ","));
                }
            });
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            List<Table> tableList = null;
            try {
                tableList = DBUtil.queryTableList(ParamConfigTab.this.getDbName());
                myModel = new MyAbstractTableModel();
                Object[][] rowData = new Object[tableList.size()][columnNames.length];
                if (tableList != null && !tableList.isEmpty()) {
                    int j = 0;
                    for (int i = 0; i < tableList.size(); i++) {
                        Table t = tableList.get(i);
                        System.out.println(t.getTableName());
                        rowData[j][0] = j+1;
                        rowData[j][1] = new Boolean(false);
                        rowData[j][2] = t.getTableName();
                        rowData[j][3] = t.getTableDescription();
                        j++;
                    }
                    myModel.setHead(columnNames);
                    myModel.setTypeArray(typeArray);
                    myModel.setData(rowData);
                    table.setModel(myModel);
                    table.getColumnModel().getColumn(0).setPreferredWidth(30);
                    table.getColumnModel().getColumn(1).setPreferredWidth(30);
                    table.getColumnModel().getColumn(2).setPreferredWidth(140);
                    table.getColumnModel().getColumn(3).setPreferredWidth(100);
                    table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);

                    chk = new JCheckBox();
                    table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(chk));
                    table.revalidate();
                }
                this.setVisible(true);
            } catch (Exception ee) {
                AgCodeMain.log("数据库没有建立可以用的连接!", Color.red, true);
                ee.printStackTrace();
                JOptionPane.showMessageDialog(null, "数据库连接失败!", "提示", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private String dbName;

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }
}
